home *** CD-ROM | disk | FTP | other *** search
/ PC PowerPlay 58 / pcpp58a.iso / extras / quake 3 source / Q3A_ToolSource.exe / Main / bsp.c < prev    next >
Encoding:
C/C++ Source or Header  |  2001-01-02  |  11.7 KB  |  580 lines

  1. #include "qbsp.h"
  2.  
  3. #ifdef _WIN32
  4. #ifdef _TTIMOBUILD
  5. #include "pakstuff.h"
  6. #else
  7. #include "../libs/pakstuff.h"
  8. #endif
  9. extern HWND hwndOut;
  10. #endif
  11.  
  12. char        source[1024];
  13. char    tempsource[1024];
  14. char        name[1024];
  15.  
  16. vec_t        microvolume = 1.0;
  17. qboolean    glview;
  18. qboolean    nodetail;
  19. qboolean    fulldetail;
  20. qboolean    onlyents;
  21. qboolean    onlytextures;
  22. qboolean    nowater;
  23. qboolean    nofill;
  24. qboolean    noopt;
  25. qboolean    leaktest;
  26. qboolean    verboseentities;
  27. qboolean    noCurveBrushes;
  28. qboolean    fakemap;
  29. qboolean    notjunc;
  30. qboolean    nomerge;
  31. qboolean    nofog;
  32. qboolean    nosubdivide;
  33. qboolean    testExpand;
  34. qboolean    showseams;
  35.  
  36. char        outbase[32];
  37.  
  38. int            entity_num;
  39.  
  40. /*
  41. ============
  42. ProcessWorldModel
  43.  
  44. ============
  45. */
  46. void ProcessWorldModel( void ) {
  47.     entity_t    *e;
  48.     tree_t        *tree;
  49.     bspface_t    *faces;
  50.     qboolean    leaked;
  51.  
  52.     BeginModel();
  53.  
  54.     e = &entities[0];
  55.     e->firstDrawSurf = 0;//numMapDrawSurfs;
  56.  
  57.     // check for patches with adjacent edges that need to LOD together
  58.     PatchMapDrawSurfs( e );
  59.  
  60.     // build an initial bsp tree using all of the sides
  61.     // of all of the structural brushes
  62.     faces = MakeStructuralBspFaceList ( entities[0].brushes );
  63.     tree = FaceBSP( faces );
  64.     MakeTreePortals (tree);
  65.     FilterStructuralBrushesIntoTree( e, tree );
  66.  
  67.     // see if the bsp is completely enclosed
  68.     if ( FloodEntities (tree) ) {
  69.         // rebuild a better bsp tree using only the
  70.         // sides that are visible from the inside
  71.         FillOutside (tree->headnode);
  72.  
  73.         // chop the sides to the convex hull of
  74.         // their visible fragments, giving us the smallest
  75.         // polygons 
  76.         ClipSidesIntoTree( e, tree );
  77.  
  78.         faces = MakeVisibleBspFaceList( entities[0].brushes );
  79.         FreeTree (tree);
  80.         tree = FaceBSP( faces );
  81.         MakeTreePortals( tree );
  82.         FilterStructuralBrushesIntoTree( e, tree );
  83.         leaked = qfalse;
  84.     } else {
  85.         _printf ("**********************\n");
  86.         _printf ("******* leaked *******\n");
  87.         _printf ("**********************\n");
  88.         LeakFile (tree);
  89.         if ( leaktest ) {
  90.             _printf ("--- MAP LEAKED, ABORTING LEAKTEST ---\n");
  91.             exit (0);
  92.         }
  93.         leaked = qtrue;
  94.  
  95.         // chop the sides to the convex hull of
  96.         // their visible fragments, giving us the smallest
  97.         // polygons 
  98.         ClipSidesIntoTree( e, tree );
  99.     }
  100.  
  101.     // save out information for visibility processing
  102.     NumberClusters( tree );
  103.     if ( !leaked ) {
  104.         WritePortalFile( tree );
  105.     }
  106.     if ( glview ) {
  107.         // dump the portals for debugging
  108.         WriteGLView( tree, source );
  109.     }
  110.     FloodAreas (tree);
  111.  
  112.     // add references to the detail brushes
  113.     FilterDetailBrushesIntoTree( e, tree );
  114.  
  115.     // create drawsurfs for triangle models
  116.     AddTriangleModels( tree );
  117.  
  118.     // drawsurfs that cross fog boundaries will need to
  119.     // be split along the bound
  120.     if ( !nofog ) {
  121.         FogDrawSurfs();        // may fragment drawsurfs
  122.     }
  123.  
  124.     // subdivide each drawsurf as required by shader tesselation
  125.     if ( !nosubdivide ) {
  126.         SubdivideDrawSurfs( e, tree );
  127.     }
  128.  
  129.     // merge together all common shaders on the same plane and remove 
  130.     // all colinear points, so extra tjunctions won't be generated
  131.     if ( !nomerge ) {
  132.         MergeSides( e, tree );        // !@# testing
  133.     }
  134.  
  135.     // add in any vertexes required to fix tjunctions
  136.     if ( !notjunc ) {
  137.         FixTJunctions( e );
  138.     }
  139.  
  140.     // allocate lightmaps for faces and patches
  141.     AllocateLightmaps( e );
  142.  
  143.     // add references to the final drawsurfs in the apropriate clusters
  144.     FilterDrawsurfsIntoTree( e, tree );
  145.  
  146.     EndModel( tree->headnode );
  147.  
  148.     FreeTree (tree);
  149. }
  150.  
  151. /*
  152. ============
  153. ProcessSubModel
  154.  
  155. ============
  156. */
  157. void ProcessSubModel( void ) {
  158.     entity_t    *e;
  159.     tree_t        *tree;
  160.     bspbrush_t    *b, *bc;
  161.     node_t        *node;
  162.  
  163.     BeginModel ();
  164.  
  165.     e = &entities[entity_num];
  166.     e->firstDrawSurf = numMapDrawSurfs;
  167.  
  168.     PatchMapDrawSurfs( e );
  169.  
  170.     // just put all the brushes in an empty leaf
  171.     // FIXME: patches?
  172.     node = AllocNode();
  173.     node->planenum = PLANENUM_LEAF;
  174.     for ( b = e->brushes ; b ; b = b->next ) {
  175.         bc = CopyBrush( b );
  176.         bc->next = node->brushlist;
  177.         node->brushlist = bc;
  178.     }
  179.  
  180.     tree = AllocTree();
  181.     tree->headnode = node;
  182.  
  183.     ClipSidesIntoTree( e, tree );
  184.  
  185.     // subdivide each drawsurf as required by shader tesselation or fog
  186.     if ( !nosubdivide ) {
  187.         SubdivideDrawSurfs( e, tree );
  188.     }
  189.  
  190.     // merge together all common shaders on the same plane and remove 
  191.     // all colinear points, so extra tjunctions won't be generated
  192.     if ( !nomerge ) {
  193.         MergeSides( e, tree );        // !@# testing
  194.     }
  195.  
  196.     // add in any vertexes required to fix tjunctions
  197.     if ( !notjunc ) {
  198.         FixTJunctions( e );
  199.     }
  200.  
  201.     // allocate lightmaps for faces and patches
  202.     AllocateLightmaps( e );
  203.  
  204.     // add references to the final drawsurfs in the apropriate clusters
  205.     FilterDrawsurfsIntoTree( e, tree );
  206.  
  207.     EndModel ( node );
  208.  
  209.     FreeTree( tree );
  210. }
  211.  
  212.  
  213. /*
  214. ============
  215. ProcessModels
  216. ============
  217. */
  218. void ProcessModels (void)
  219. {
  220.     qboolean    oldVerbose;
  221.     entity_t    *entity;
  222.  
  223.     oldVerbose = verbose;
  224.  
  225.     BeginBSPFile ();
  226.  
  227.     for ( entity_num=0 ; entity_num< num_entities ; entity_num++ ) {
  228.         entity = &entities[entity_num];
  229.     
  230.         if ( !entity->brushes && !entity->patches ) {
  231.             continue;
  232.         }
  233.  
  234.         qprintf ("############### model %i ###############\n", nummodels);
  235.         if (entity_num == 0)
  236.             ProcessWorldModel ();
  237.         else
  238.             ProcessSubModel ();
  239.  
  240.         if (!verboseentities)
  241.             verbose = qfalse;    // don't bother printing submodels
  242.     }
  243.  
  244.     verbose = oldVerbose;
  245. }
  246.  
  247. /*
  248. ============
  249. Bspinfo
  250. ============
  251. */
  252. void Bspinfo( int count, char **fileNames ) {
  253.     int        i;
  254.     char    source[1024];
  255.     int            size;
  256.     FILE        *f;
  257.  
  258.     if ( count < 1 ) {
  259.         _printf( "No files to dump info for.\n");
  260.         return;
  261.     }
  262.  
  263.     for ( i = 0 ; i < count ; i++ ) {
  264.         _printf ("---------------------\n");
  265.         strcpy (source, fileNames[ i ] );
  266.         DefaultExtension (source, ".bsp");
  267.         f = fopen (source, "rb");
  268.         if (f)
  269.         {
  270.             size = Q_filelength (f);
  271.             fclose (f);
  272.         }
  273.         else
  274.             size = 0;
  275.         _printf ("%s: %i\n", source, size);
  276.         
  277.         LoadBSPFile (source);        
  278.         PrintBSPFileSizes ();
  279.         _printf ("---------------------\n");
  280.     }
  281. }
  282.  
  283.  
  284. /*
  285. ============
  286. OnlyEnts
  287. ============
  288. */
  289. void OnlyEnts( void ) {
  290.     char out[1024];
  291.  
  292.     sprintf (out, "%s.bsp", source);
  293.     LoadBSPFile (out);
  294.     num_entities = 0;
  295.  
  296.     LoadMapFile (name);
  297.     SetModelNumbers ();
  298.     SetLightStyles ();
  299.  
  300.     UnparseEntities ();
  301.  
  302.     WriteBSPFile (out);
  303. }
  304.  
  305.  
  306. /*
  307. ============
  308. OnlyTextures
  309. ============
  310. */
  311. void OnlyTextures( void ) {        // FIXME!!!
  312.     char    out[1024];
  313.     int        i;
  314.  
  315.     Error( "-onlytextures isn't working now..." );
  316.  
  317.     sprintf (out, "%s.bsp", source);
  318.  
  319.     LoadMapFile (name);
  320.  
  321.     LoadBSPFile (out);
  322.  
  323.     // replace all the drawsurface shader names
  324.     for ( i = 0 ; i < numDrawSurfaces ; i++ ) {
  325.     }
  326.  
  327.     WriteBSPFile (out);
  328. }
  329.  
  330.  
  331. /*
  332. ============
  333. main
  334. ============
  335. */
  336. int LightMain( int argc, char **argv );
  337. int VLightMain (int argc, char **argv);
  338. int VisMain( int argc, char **argv );
  339.  
  340. int main (int argc, char **argv) {
  341.     int        i;
  342.     double        start, end;
  343.     char        path[1024];
  344.  
  345.     _printf ("Q3Map v1.0r (c) 1999 Id Software Inc.\n");
  346.   
  347.     if ( argc < 2 ) {
  348.         Error ("usage: q3map [options] mapfile");
  349.     }
  350.  
  351.     // check for general program options
  352.     if (!strcmp(argv[1], "-info")) {
  353.         Bspinfo( argc - 2, argv + 2 );
  354.         return 0;
  355.     }
  356.     if (!strcmp(argv[1], "-light")) {
  357.         LightMain( argc - 1, argv + 1 );
  358.         return 0;
  359.     }
  360.     if (!strcmp(argv[1], "-vlight")) {
  361.         VLightMain( argc - 1, argv + 1 );
  362.         return 0;
  363.     }
  364.     if (!strcmp(argv[1], "-vis")) {
  365.         VisMain( argc - 1, argv + 1 );
  366.         return 0;
  367.     }
  368.  
  369.     // do a bsp if nothing else was specified
  370.  
  371.     _printf ("---- q3map ----\n");
  372.  
  373.   tempsource[0] = '\0';
  374.  
  375.     for (i=1 ; i<argc ; i++)
  376.     {
  377.         if (!strcmp(argv[i],"-tempname"))
  378.     {
  379.       strcpy(tempsource, argv[++i]);
  380.     }
  381.         else if (!strcmp(argv[i],"-threads"))
  382.         {
  383.             numthreads = atoi (argv[i+1]);
  384.             i++;
  385.         }
  386.         else if (!strcmp(argv[i],"-glview"))
  387.         {
  388.             glview = qtrue;
  389.         }
  390.         else if (!strcmp(argv[i], "-v"))
  391.         {
  392.             _printf ("verbose = true\n");
  393.             verbose = qtrue;
  394.         }
  395.         else if (!strcmp(argv[i], "-draw"))
  396.         {
  397.             _printf ("drawflag = true\n");
  398.             drawflag = qtrue;
  399.         }
  400.         else if (!strcmp(argv[i], "-nowater"))
  401.         {
  402.             _printf ("nowater = true\n");
  403.             nowater = qtrue;
  404.         }
  405.         else if (!strcmp(argv[i], "-noopt"))
  406.         {
  407.             _printf ("noopt = true\n");
  408.             noopt = qtrue;
  409.         }
  410.         else if (!strcmp(argv[i], "-nofill"))
  411.         {
  412.             _printf ("nofill = true\n");
  413.             nofill = qtrue;
  414.         }
  415.         else if (!strcmp(argv[i], "-nodetail"))
  416.         {
  417.             _printf ("nodetail = true\n");
  418.             nodetail = qtrue;
  419.         }
  420.         else if (!strcmp(argv[i], "-fulldetail"))
  421.         {
  422.             _printf ("fulldetail = true\n");
  423.             fulldetail = qtrue;
  424.         }
  425.         else if (!strcmp(argv[i], "-onlyents"))
  426.         {
  427.             _printf ("onlyents = true\n");
  428.             onlyents = qtrue;
  429.         }
  430.         else if (!strcmp(argv[i], "-onlytextures"))
  431.         {
  432.             _printf ("onlytextures = true\n");    // FIXME: make work again!
  433.             onlytextures = qtrue;
  434.         }
  435.         else if (!strcmp(argv[i], "-micro"))
  436.         {
  437.             microvolume = atof(argv[i+1]);
  438.             _printf ("microvolume = %f\n", microvolume);
  439.             i++;
  440.         }
  441.         else if (!strcmp(argv[i], "-nofog"))
  442.         {
  443.             _printf ("nofog = true\n");
  444.             nofog = qtrue;
  445.         }
  446.         else if (!strcmp(argv[i], "-nosubdivide"))
  447.         {
  448.             _printf ("nosubdivide = true\n");
  449.             nosubdivide = qtrue;
  450.         }
  451.         else if (!strcmp(argv[i], "-leaktest"))
  452.         {
  453.             _printf ("leaktest = true\n");
  454.             leaktest = qtrue;
  455.         }
  456.         else if (!strcmp(argv[i], "-verboseentities"))
  457.         {
  458.             _printf ("verboseentities = true\n");
  459.             verboseentities = qtrue;
  460.         }
  461.         else if (!strcmp(argv[i], "-nocurves"))
  462.         {
  463.             noCurveBrushes = qtrue;
  464.             _printf ("no curve brushes\n");
  465.         }
  466.         else if (!strcmp(argv[i], "-notjunc"))
  467.         {
  468.             notjunc = qtrue;
  469.             _printf ("no tjunction fixing\n");
  470.         }
  471.         else if (!strcmp(argv[i], "-expand"))
  472.         {
  473.             testExpand = qtrue;
  474.             _printf ("Writing expanded.map.\n");
  475.         }
  476.         else if (!strcmp(argv[i], "-showseams"))
  477.         {
  478.             showseams = qtrue;
  479.             _printf ("Showing seams on terrain.\n");
  480.         }
  481.         else if (!strcmp (argv[i],"-tmpout"))
  482.         {
  483.             strcpy (outbase, "/tmp");
  484.         }
  485.         else if (!strcmp (argv[i],"-fakemap"))
  486.         {
  487.             fakemap = qtrue;
  488.             _printf( "will generate fakemap.map\n");
  489.         }
  490.         else if (!strcmp(argv[i], "-samplesize"))
  491.         {
  492.             samplesize = atoi(argv[i+1]);
  493.             if (samplesize < 1) samplesize = 1;
  494.             i++;
  495.             _printf("lightmap sample size is %dx%d units\n", samplesize, samplesize);
  496.         }
  497.         else if (argv[i][0] == '-')
  498.             Error ("Unknown option \"%s\"", argv[i]);
  499.         else
  500.             break;
  501.     }
  502.  
  503.     if (i != argc - 1)
  504.         Error ("usage: q3map [options] mapfile");
  505.  
  506.     start = I_FloatTime ();
  507.  
  508.     ThreadSetDefault ();
  509.     //numthreads = 1;        // multiple threads aren't helping because of heavy malloc use
  510.     SetQdirFromPath (argv[i]);
  511.  
  512. #ifdef _WIN32
  513.   InitPakFile(gamedir, NULL);
  514. #endif
  515.  
  516.     strcpy (source, ExpandArg (argv[i]));
  517.     StripExtension (source);
  518.  
  519.     // delete portal and line files
  520.     sprintf (path, "%s.prt", source);
  521.     remove (path);
  522.     sprintf (path, "%s.lin", source);
  523.     remove (path);
  524.  
  525.     strcpy (name, ExpandArg (argv[i]));    
  526.     if ( strcmp(name + strlen(name) - 4, ".reg" ) ) {
  527.         // if we are doing a full map, delete the last saved region map
  528.         sprintf (path, "%s.reg", source);
  529.         remove (path);
  530.  
  531.         DefaultExtension (name, ".map");    // might be .reg
  532.     }
  533.  
  534.     //
  535.     // if onlyents, just grab the entites and resave
  536.     //
  537.     if ( onlyents ) {
  538.         OnlyEnts();
  539.         return 0;
  540.     }
  541.  
  542.     //
  543.     // if onlytextures, just grab the textures and resave
  544.     //
  545.     if ( onlytextures ) {
  546.         OnlyTextures();
  547.         return 0;
  548.     }
  549.  
  550.     //
  551.     // start from scratch
  552.     //
  553.     LoadShaderInfo();
  554.  
  555.   // load original file from temp spot in case it was renamed by the editor on the way in
  556.   if (strlen(tempsource) > 0) {
  557.       LoadMapFile (tempsource);
  558.   } else {
  559.       LoadMapFile (name);
  560.   }
  561.  
  562.     SetModelNumbers ();
  563.     SetLightStyles ();
  564.  
  565.     ProcessModels ();
  566.  
  567.     EndBSPFile();
  568.  
  569.     end = I_FloatTime ();
  570.     _printf ("%5.0f seconds elapsed\n", end-start);
  571.  
  572.   // remove temp name if appropriate
  573.   if (strlen(tempsource) > 0) {
  574.     remove(tempsource);
  575.   }
  576.  
  577.     return 0;
  578. }
  579.  
  580.